package com.warningrc.module.user.interceptor;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.warningrc.system.Constants;

@SuppressWarnings("serial")
public class UserLoginInterceptor extends AbstractInterceptor {
	private List<Pattern> urlPatterns;
	private List<Pattern> encludePatterns;
	private String url;

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public List<Pattern> getEncludePatterns() {
		return encludePatterns;
	}

	public void setEncludePatterns(String patterns) {
		if (null != patterns && patterns.trim().length() != 0) {
			List<Pattern> list = new ArrayList<Pattern>();
			String[] tokens = patterns.split(",");
			for (String token : tokens) {
				list.add(Pattern.compile(token.trim()));
			}
			this.encludePatterns = Collections.unmodifiableList(list);
		}
	}

	public List<Pattern> getUrlPatterns() {
		return urlPatterns;
	}

	public void setUrlPatterns(String patterns) {
		if (null != patterns && patterns.trim().length() != 0) {
			List<Pattern> list = new ArrayList<Pattern>();
			String[] tokens = patterns.split(",");
			for (String token : tokens) {
				list.add(Pattern.compile(token.trim()));
			}
			this.urlPatterns = Collections.unmodifiableList(list);
		}
	}

	/**
	 * 验证Action是否在登陆验证排除列表中
	 * 
	 * @param invocation
	 * @return
	 */
	public boolean encludeLoginValidation(ActionInvocation invocation) {
		if (this.encludePatterns == null)
			return false;
		else {
			String uri = invocation.getProxy().getNamespace() + "/"
					+ invocation.getProxy().getActionName();
			for (Pattern pattern : encludePatterns) {
				if (pattern.matcher(uri).matches()) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 验证是否需要登陆验证，如果需要验证返回true
	 * 
	 * @param invocation
	 * @return
	 */
	public boolean needLoginValidation(ActionInvocation invocation) {
		if (this.urlPatterns == null)
			return true;
		else {
			String uri = invocation.getProxy().getNamespace() + "/"
					+ invocation.getProxy().getActionName();
			for (Pattern pattern : urlPatterns) {
				if (pattern.matcher(uri).matches()) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void destroy() {
		urlPatterns = null;
		encludePatterns = null;
	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		if (needLoginValidation(invocation)
				&& !encludeLoginValidation(invocation)) {
			Serializable userId = (Serializable) ActionContext.getContext()
					.getSession().get(Constants.USER_LOGINED_MESSAGE);
			if (userId == null) {
				HttpServletRequest request = ServletActionContext.getRequest();
				String returnUrl = getWebUrl(request);
				String httpMethod = request.getMethod();
				if ("get".equalsIgnoreCase(httpMethod))
					returnUrl += invocation.getProxy().getNamespace() + "/"
							+ invocation.getProxy().getActionName() + "?"
							+ request.getQueryString();
				// String httpreferer = ServletActionContext.getRequest()
				// .getHeader(Constants.HTTP_HEADER_REFERER);
				invocation.getStack().set("url",
						URLEncoder.encode(returnUrl, "utf-8"));
				return "login";
			}
			return invocation.invoke();
		} else
			return invocation.invoke();
	}

	public static String getWebUrl(HttpServletRequest request) {
		String url = request.getScheme() + "://" + request.getServerName()
				+ ":" + request.getServerPort() + request.getContextPath();
		return url;
	}

	public static void main(String[] args) throws UnsupportedEncodingException {
		System.out.println(URLEncoder.encode("http://127.0.0.1:80/fw/system/test?a=bc&c=d", "utf-8"));
		System.out.println(URLDecoder.decode(URLEncoder.encode("http://127.0.0.1:80/fw/system/test?a=bc&c=d", "utf-8"), "utf-8"));
	}
}
